#pragma once


#include"EventLoop.h"
#include"Acceptor.h"
#include"InetAddress.h"
#include"noncopyable.h"
#include"EventLoopThreadPool.h"
#include"Callback.h"
#include"TcpConnection.h"
#include"Buffer.h"


#include<functional>
#include<memory>
#include<unordered_map>
#include<atomic>
#include<string>

class TcpServer : noncopyable
{
public:
    using ThreadInitCallback = std::function<void(EventLoop*)>;

    enum Option
    {
        KNoReusePort,
        KReusePort,
    };
    TcpServer(EventLoop* loop, const InetAddress& ListenAddr, const std::string& nameArg, Option option = KNoReusePort);
    ~TcpServer();

    void setThreadInitCallback(const ThreadInitCallback& cb) {threadInitCallback_ = cb;}
    void setConnectionCallback(const ConnectionCallback& cb) {connectionCallback_ = cb;}
    void setMessageCallback(const MessageCallback& cb) {messageCallback_ = cb;}
    void setWriteCompleteCallback(const WriteCompleteCallback& cb) {writeCompleteCallback_ = cb;}
    
    
    void setThreadNum(int numThreads);

    //开启服务器监听，
    void start();
private:
    void newConnection(int sockfd, const InetAddress &peerAddr);
    void removeConnection(const TcpConnectionPtr &conn);
    void removeConnectionInLoop(const TcpConnectionPtr &conn);

    using ConnectionMap = std::unordered_map<std::string, TcpConnectionPtr>;

    EventLoop* loop_;//用户传的loop,baseloop
    const std::string ipPort_;
    const std::string name_;

    std::unique_ptr<Acceptor> acceptor_;//运行在mainloop，监听新连接
    
    std::shared_ptr<EventLoopThreadPool>  threadPool_;

    //用户给的回调，交给TcpConnection
    ConnectionCallback connectionCallback_;//有新连接的callback
    MessageCallback messageCallback_;//有读写消息的callback
    WriteCompleteCallback writeCompleteCallback_;//消息发送完成的callback
    ThreadInitCallback threadInitCallback_;//loop线程初始化的回调

    std::atomic_int started_;

    int nextConnId_;
    ConnectionMap connections_;
};

